﻿using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace 收入分析.Services;

/***这里面写的代码不会给覆盖,如果要重新生成请删除 Repository.cs ***/

/// <summary>
/// 仓储模式
/// </summary>
/// <typeparam name="T"></typeparam>
public class Repository<T> : SimpleClient<T> where T : class, new()
{

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="context"></param>
    public Repository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
    {
        if (context == null)
        {
            base.Context = Db;
        }
    }
    static string dbName = Path.Combine(Environment.CurrentDirectory, "xczx.db");
    /// <summary>
    /// SqlSugarScope操作数据库是线程安的可以单例
    /// </summary>
    public static SqlSugarScope Db = new(new ConnectionConfig()
    {
        DbType = SqlSugar.DbType.Sqlite,
        ConnectionString = @$"DataSource={dbName}",
        IsAutoCloseConnection = true,
        MoreSettings = new ConnMoreSettings
        {
            IsCorrectErrorSqlParameterName = true, // 5.1.4.111及以上版本
        },
        ConfigureExternalServices = new ConfigureExternalServices
        {
            //注意:  这儿AOP设置不能少
            EntityService = (type, column) =>
            {
                //修改列
                // 增加可空类型支持
                /***低版本C#写法***/
                // int?  decimal?这种 isnullable=true 不支持string(下面.NET 7支持)
                //if (p.IsPrimarykey == false && c.PropertyType.IsGenericType &&
                //c.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                //{
                //    p.IsNullable = true;
                //}

                /***高版C#写法***/
                //支持string?和string  
                if (column.IsPrimarykey == false && new NullabilityInfoContext()
                 .Create(type).WriteState is NullabilityState.Nullable)
                {
                    column.IsNullable = true;
                }
                //column.DbColumnName = $"`{column.DbColumnName}`";
            },

            EntityNameService = (type, entity) =>
            {
                //修改表        
                entity.DbTableName = $"`{entity.DbTableName}`";
            },
        }
    },
     db =>
     {
         //如果用单例配置要统一写在这儿
         db.Aop.OnLogExecuting = (s, p) =>
         {
             Debug.WriteLine(UtilMethods.GetSqlString(DbType.Sqlite,s, p));
         };

     });


    //public static ISugarQueryable<T> Use(string dbName)
    //{
    //    return AsQueryable().AS(dbName);
    //}
    //获取列信息
    //var columns=db.DbMaintenance.GetColumnInfosByTableName("表名",false);

    //public static T ConvertDic<T>(Dictionary<string, object> dic)
    //{
    //    T model = Activator.CreateInstance<T>();
    //    PropertyInfo[] modelProp = model.GetType().GetProperties();
    //    if (modelProp.Length > 0 && dic.Count() > 0)
    //    {
    //        for (int i = 0; i < modelProp.Length; i++)
    //        {
    //            PropertyInfo proInfo = modelProp[i];
    //            if (dic.ContainsKey(proInfo.Name))
    //            {
    //                object value = dic[proInfo.Name];
    //                if (!proInfo.PropertyType.IsGenericType)
    //                {
    //                    //非泛型
    //                    proInfo.SetValue(model, value == null ? null
    //                    : string.IsNullOrWhiteSpace(value.ToString()) ? null
    //                    : Convert.ChangeType(value, proInfo.PropertyType), null);
    //                }
    //                else
    //                {
    //                    //泛型Nullable<>
    //                    Type genericTypeDefinition = proInfo.PropertyType.GetGenericTypeDefinition();
    //                    if (genericTypeDefinition == typeof(Nullable<>))
    //                    {
    //                        proInfo.SetValue(model, value == null ? null
    //                        : string.IsNullOrWhiteSpace(value.ToString()) ? null
    //                        : Convert.ChangeType(value, Nullable.GetUnderlyingType(proInfo.PropertyType)), null);
    //                    }
    //                }
    //            }
    //        }
    //    }
    //    return model;
    //}

    internal static async Task<int> BulkCopy(string table, IList list)
    {
        if (list is List<T> list2)
            return await Db.Fastest<T>().AS(table).PageSize(5000).BulkCopyAsync(list2);//MySql连接字符串要加AllowLoadLocalInfile=true
        return 0;
    }

    /// <summary>
    /// 仓储扩展方法:单表查询通用分页 
    /// </summary>
    /// <returns></returns>
    public object CommonPage(QueryParameters pars, int pageIndex, int pagesize)
    {
        int tolCount = 0;
        var sugarParamters = pars.Parameters.Select(it => (IConditionalModel)new ConditionalModel()
        {
            ConditionalType = it.ConditionalType,
            FieldName = it.FieldName,
            FieldValue = it.FieldValue
        }).ToList();
        var query = Db.Queryable<T>();
        if (pars.OrderBys != null)
        {
            foreach (var item in pars.OrderBys)
            {
                query.OrderBy(item.ToSqlFilter());//格式 id asc或者 id desc
            }
        }
        var result = query.Where(sugarParamters).ToPageList(1, 2, ref tolCount);
        return new
        {
            count = tolCount,
            data = result
        };
    }

    /// <summary>
    /// 仓储扩展方法:多表查询通用分页 
    /// 用法  CommonPage(db.Queryable<JoinTable1,JoinTable2>(...).Select(it=new class(){..}).MergeTable(),pars,orderbys,pageIndex,pagesize)
    /// </summary>
    /// <returns></returns>
    public object CommonPage<ViewModel>(ISugarQueryable<ViewModel> query, QueryParameters pars, int pageIndex, int pagesize)
    {
        int tolCount = 0;
        var sugarParamters = pars.Parameters.Select(it => (IConditionalModel)new ConditionalModel()
        {
            ConditionalType = it.ConditionalType,
            FieldName = it.FieldName,
            FieldValue = it.FieldValue
        }).ToList();
        if (pars.OrderBys != null)
        {
            foreach (var item in pars.OrderBys)
            {
                query.OrderBy(item.ToSqlFilter());//格式 id asc或者 id desc
            }
        }
        var result = query.Where(sugarParamters).ToPageList(1, 2, ref tolCount);
        return new
        {
            count = tolCount,
            data = result
        };
    }

}
/// <summary>
/// 通用查询参数
/// </summary>
public class QueryParameters
{
    public List<QueryParameter>? Parameters { get; set; }
    public List<string> OrderBys { get; set; }

}
/// <summary>
/// 通用查询参数
/// </summary>
public class QueryParameter
{
    public string FieldName { get; set; }
    public string FieldValue { get; set; }
    public ConditionalType ConditionalType
    {
        get; set;
    }

}